import time

import allure
from appium.webdriver.common.appiumby import AppiumBy

from base.log_util import logger

black_list = [
    (AppiumBy.XPATH, "//*[@text='确定']"),
    (AppiumBy.XPATH, "//*[@text='取消']")
]


# 传入的 fun 相当于 search_element(self, loc, timeout=10, poll_frequency=0.5)
def app_exception_handle(fun):
    def run(*args, **kwargs):
        # basepage 相当于传入的第一个参数 self
        self = args[0]
        try:
            # logger.info(f"开始查找元素：{args[1]}")
            return fun(*args, **kwargs)
        except Exception as e:
            logger.warning("未找到元素，处理异常")
            # 遇到异常截图
            timestamp = int(time.time())
            # 设置文件路径
            image_path = f"./images/image_{timestamp}.PNG"
            page_source_path = f"./page_source/{timestamp}_page_source.html"

            # 保存page_source
            with open(page_source_path, "w", encoding="u8") as f:
                f.write(self.driver.page_source)
            # 保存异常截图
            self.driver.save_screenshot(image_path)

            # allure添加图片
            allure.attach.file(image_path, name="image", attachment_type=allure.attachment_type.PNG)

            # attachment_type=allure.attachment_type.HTML，html的内容在allure报告中会以页面的形式展示，所以用TEXT格式
            # allure.attach.file(page_source_path, name="page_source", attachment_type=allure.attachment_type.HTML)
            # allure添加page_source
            allure.attach.file(page_source_path, name="page_source", attachment_type=allure.attachment_type.TEXT)

            # 遍历黑名单列表，处理可能出现的弹窗
            for b in black_list:
                # 设置隐式等待时间为 1 s
                self.driver.implicitly_wait(1)
                #  查找黑名单中的每一个元素
                eles = self.driver.find_elements(*b)
                if len(eles) > 0:
                    # 点击弹框
                    eles[0].click()
                    # 恢复隐式等待设置
                    self.driver.implicitly_wait(20)
                    # 继续查找元素
                    return fun(*args, **kwargs)
            logger.error(f"遍历黑名单，仍未找到元素，异常信息为 ====> {e}")
            raise e
    return run
